<?php

declare(strict_types=1);

namespace MonologMysql\Formatter;

use Carbon\Carbon;
use Hyperf\Utils\Arr;
use Monolog\Formatter\FormatterInterface;

class MysqlFormatter implements FormatterInterface
{
    protected string $dateFormat;
    protected int    $expireDay;

    public function __construct(string $dateFormat = 'Y-m-d H:i:s', int $expireDay = 30)
    {
        $this->dateFormat = $dateFormat;
        $this->expireDay  = $expireDay;
    }

    /**
     * @param array $record
     *
     * @return array
     */
    public function format(array $record): array
    {
        return [
            'request_id'   => Arr::get($record, 'context.request_id', ''),
            'business_key' => Arr::get($record, 'context.business_key', ''),
            'channel'      => Arr::get($record, 'channel', ''),
            'message'      => Arr::get($record, 'message', ''),
            'level'        => Arr::get($record, 'level', 0),
            'context'      => json_encode(Arr::merge(
                $this->formatContext(Arr::get($record, 'context')),
                Arr::get($record, 'extra'),
            ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
            'log_at'       => Arr::get($record, 'context.log_at', $record['datetime']->format($this->dateFormat)),
            'expired_at'   => Carbon::now()->addDays($this->expireDay)->format($this->dateFormat),
        ];
    }

    /**
     * @param array $records
     *
     * @return array
     */
    public function formatBatch(array $records): array
    {
        foreach ($records as $key => $record) {
            $records[$key] = $this->format($record);
        }
        return $records;
    }

    /**
     * @param array $context
     *
     * @return array
     */
    protected function formatContext(array $context): array
    {
        Arr::forget($context, ['request_id', 'business_key', 'log_at']);
        return $context;
    }
}
